package cn.itcast.bos.action.system;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionContext;

import cn.itcast.bos.domain.system.User;
import cn.itcast.bos.service.system.UserService;
import cn.itcast.fore.web.action.common.BaseAction;

//用户操作
@Controller
@Scope("prototype")
public class UserAction extends BaseAction<User> {

	// 登录（认证过程）
	// @Action(value = "user_login", results = { @Result(type = REDIRECT,
	// location = "/index.html"), @Result(name = INPUT, type = REDIRECT,
	// location = "/login.html") })
	//
	// public String login() {
	// // 用户输入的用户名密码封装到了model中
	// // ====Shiro的认证
	// // 获取subject对象
	// Subject subject = SecurityUtils.getSubject();
	// // 创建一个令牌对象:参数是用户输入的
	// UsernamePasswordToken token = new
	// UsernamePasswordToken(model.getUsername(), model.getPassword());
	// // 调用subject对象登录
	// // 参数：令牌
	// //结果map
	// Map<String, Object> resultMap=new HashMap<>();
	// try {
	// subject.login(token);
	// // 登录成功,跳转到主页
	// return SUCCESS;
	// } catch (UnknownAccountException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// // 登录失败
	// return LOGIN;
	// } catch (LockedAccountException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// // 登录失败
	// return LOGIN;
	// }
	//
	// }
	@Action("user_login")
	public String login() {
		// 逻辑：操作shiro的subject即可。

		// 获取subject
		Subject subject = SecurityUtils.getSubject();

		// 创建用户令牌
		UsernamePasswordToken token = new UsernamePasswordToken(model.getUsername(), model.getPassword());
		// UsernamePasswordToken token=new UsernamePasswordToken
		// (model.getUsername(), MD5Utils.md5(model.getPassword()));

		// 结果map
		Map<String, Object> resultMap = new HashMap<>();

		try {
			// 认证（登录）
			// 参数：令牌token
			subject.login(token);
			// AuthenticationToken
			// 登录成功
			resultMap.put("result", true);

		} catch (UnknownAccountException e) {
			e.printStackTrace();
			// 登录失败:用户名不存在
			resultMap.put("result", false);
			resultMap.put("message", "用户名不存在！");
		} catch (LockedAccountException e) {
			e.printStackTrace();
			// 登录失败:帐号被锁定
			resultMap.put("result", false);
			resultMap.put("message", "帐号被锁定，请联系管理员，交钱。");
		} catch (IncorrectCredentialsException e) {
			e.printStackTrace();
			// 登录失败:密码不正确
			resultMap.put("result", false);
			resultMap.put("message", "密码不正确。");
		}
		// 压入栈顶
		ActionContext.getContext().getValueStack().push(resultMap);

		return JSON;

	}

	// 注销用户
	@Action(value = "user_logout", results = { @Result(type = REDIRECT, location = "/login.html") })
	public String logout() {

		// shiro注销：释放了很多资源
		SecurityUtils.getSubject().logout();
		/*
		 * shiro的底层原理：也将用户对象放入“session”
		 * 该session不是httpsession，而是org.apache.shiro.session.Session
		 * Shiro可以用在任何的环境下，普通的java程序或web都可以 session规则：
		 * 如果web应用，shiro的session会封装httpsession，或理解为两者等同。用户对象确实放入了httpsession
		 * 如果不是web应用，shiro的session就和httpsession没什么关系了。 但对于开发来说，不用管。
		 */

		return SUCCESS;
	}

	// 注销用户
	@Action(value = "user_loginout", results = { @Result(type = "redirect", location = "login.html") })
	public String loginout() {
		// 注销用户，释放资源
		// 改session不一定是httpsession
		/*
		 * 关于session： shiro可以用到任何的环境 如果有web环境，则session会封装httpSession，两者基本等价
		 * 如果不是web环境，则session中没有httpSession，底层是个map，自己实现的。
		 */
		// Session session = SecurityUtils.getSubject().getSession();
		SecurityUtils.getSubject().logout();
		return SUCCESS;

	}

	@Autowired
	private UserService userService;

	// 查询所有用户
	@Action("user_list")
	public String list() {
		// 获取查询的用户用list接收
		List<User> userList = userService.findByUser();
		// 压入栈顶
		ActionContext.getContext().getValueStack().push(userList);
		return JSON;

	}

	// 属性驱动
	private String[] roleIds;

	public void setRoleIds(String[] roleIds) {
		this.roleIds = roleIds;
	}

	@Action(value = "user_add", results = { @Result(type = "redirect", location = "/pages/system/userlist.html") })
	public String add() {
		userService.saveUser(model, roleIds);
		return SUCCESS;

	}
}
